package com.sha.mumbailocal.server.impl;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.sha.mumbailocal.server.exception.UnparsableContentException;
import com.sha.mumbailocal.server.intf.IContentDataObjectCollection;
import com.sha.mumbailocal.server.intf.IContentParser;

public class CsvContentParser implements IContentParser {

	public final static String DEFAULT_FIELD_DELIMETER = ",";

	public final static String DEFAULT_RECORD_DELIMETER = System
			.getProperty("line.seperator");

	private Reader reader;

	private String fieldDelimiter;

	private String recordDelimeter;

	private String[] fields;

	private List<Map<String, String>> dataObjects;

	private IContentDataObjectCollection contentDataObjects;

	public CsvContentParser() {
		this(null);
	}

	public CsvContentParser(Reader reader) {
		this(reader, DEFAULT_FIELD_DELIMETER);
	}

	public CsvContentParser(Reader reader, String fieldDelimiter) {
		this(reader, fieldDelimiter, DEFAULT_RECORD_DELIMETER);
	}

	public CsvContentParser(Reader reader, String fieldDelimiter,
			String recordDelimiter) {
		this(reader, fieldDelimiter, recordDelimiter, null);
	}

	public CsvContentParser(Reader reader, String fieldDelimiter,
			String recordDelimiter, String[] fields) {
		this.reader = reader;
		this.fieldDelimiter = fieldDelimiter;
		this.recordDelimeter = recordDelimiter;
		this.fields = fields;
	}

	@Override
	public void parseContent() throws UnparsableContentException {
		int ch = 0;
		StringBuilder builder = new StringBuilder();
		try {
			while ((ch = reader.read()) != -1) {
				builder.append((char) ch);
			}
		} catch (IOException e) {
			throw new UnparsableContentException(e.getMessage(), e);
		}

		String content = builder.toString();
		builder.setLength(0);

		String records[] = content.split(recordDelimeter);

		dataObjects = new ArrayList<Map<String, String>>();

		int i = 0;

		if (fields == null || fields.length == 0) {
			fields = records[0].split(fieldDelimiter);
		}

		for (i = 1; i < records.length; i++) {
			String dataFields[] = records[i].split(fieldDelimiter);

			Map<String, String> dataRecord = new HashMap<String, String>();

			for (int j = 0; j < dataFields.length; j++) {
				dataRecord.put(fields[j], dataFields[j]);
			}

			dataObjects.add(dataRecord);
		}
		
		contentDataObjects = new IContentDataObjectCollection() {
			
			@Override
			public String[] getFields() {
				return fields;
			}
			
			@Override
			public List<Map<String, String>> getFieldValues() {
				return dataObjects;
			}
		};

	}

	public String getFieldDelimiter() {
		return fieldDelimiter;
	}

	public void setFieldDelimiter(String fieldDelimiter) {
		this.fieldDelimiter = fieldDelimiter;
	}

	public String getRecordDelimeter() {
		return recordDelimeter;
	}

	public void setRecordDelimeter(String recordDelimeter) {
		this.recordDelimeter = recordDelimeter;
	}

	public IContentDataObjectCollection getContentDataObjects() {
		return contentDataObjects;
	}

	public void setReader(Reader reader) {
		this.reader = reader;
	}

	public String[] getFields() {
		return fields;
	}

	public void setFields(String[] fields) {
		this.fields = fields;
	}

}
